29620d
@@ -10523,14 +10523,14 @@
private ExprNodeDesc getExprNodeDescCached(ASTNode expr, RowResolver input)
     }
 
     Map<ExprNodeDesc,String> nodeToText = new HashMap<>();
-    List<Entry<ASTNode, ExprNodeDesc>> fieldDescList = new ArrayList<>();
+    List<ASTNode> fieldDescList = new ArrayList<>();
 
     for (Map.Entry<ASTNode, ExprNodeDesc> entry : nodeOutputs.entrySet()) {
       if (!(entry.getValue() instanceof ExprNodeColumnDesc)) {
         // we need to translate the ExprNodeFieldDesc too, e.g., identifiers in
         // struct<>.
         if (entry.getValue() instanceof ExprNodeFieldDesc) {
-          fieldDescList.add(entry);
+          fieldDescList.add(entry.getKey());
         }
         continue;
       }
@@ -10551,35 +10551,28 @@
private ExprNodeDesc getExprNodeDescCached(ASTNode expr, RowResolver input)
       unparseTranslator.addTranslation(node, replacementText.toString());
     }
 
-    if (fieldDescList.size() != 0) {
-      // Sorting the list based on the length of fieldName
-      // For example, in Column[a].b.c and Column[a].b, Column[a].b should be
-      // unparsed before Column[a].b.c
-      Collections.sort(fieldDescList, new Comparator<Map.Entry<ASTNode, ExprNodeDesc>>() {
-        @Override
-        public int compare(Entry<ASTNode, ExprNodeDesc> o1, Entry<ASTNode, ExprNodeDesc> o2) {
-          ExprNodeFieldDesc fieldDescO1 = (ExprNodeFieldDesc) o1.getValue();
-          ExprNodeFieldDesc fieldDescO2 = (ExprNodeFieldDesc) o2.getValue();
-          return fieldDescO1.toString().length() < fieldDescO2.toString().length() ? -1 : 1;
-        }
-      });
-      for (Map.Entry<ASTNode, ExprNodeDesc> entry : fieldDescList) {
-        ASTNode node = entry.getKey();
-        ExprNodeFieldDesc fieldDesc = (ExprNodeFieldDesc) entry.getValue();
-        ExprNodeDesc exprNodeDesc = fieldDesc.getDesc();
-        String fieldName = fieldDesc.getFieldName();
-        StringBuilder replacementText = new StringBuilder();
-        replacementText.append(nodeToText.get(exprNodeDesc));
-        replacementText.append(".");
-        replacementText.append(HiveUtils.unparseIdentifier(fieldName, conf));
-        nodeToText.put(fieldDesc, replacementText.toString());
-        unparseTranslator.addTranslation(node, replacementText.toString());
+    for (ASTNode node : fieldDescList) {
+      Map<ASTNode, String> map = translateFieldDesc(node);
+      for (Entry<ASTNode, String> entry : map.entrySet()) {
+        unparseTranslator.addTranslation(entry.getKey(), entry.getValue());
       }
     }
 
     return nodeOutputs;
   }
 
+  private Map<ASTNode, String> translateFieldDesc(ASTNode node) {
+    Map<ASTNode, String> map = new HashMap<>();
+    if (node.getType() == HiveParser.DOT) {
+      for (Node child : node.getChildren()) {
+        map.putAll(translateFieldDesc((ASTNode) child));
+      }
+    } else if (node.getType() == HiveParser.Identifier) {
+      map.put(node, HiveUtils.unparseIdentifier(node.getText(), conf));
+    }
+    return map;
+  }
+
   @Override
   public void validate() throws SemanticException {
     LOG.debug("validation start");
